package com.xyht.medicine_management_system.modules.medicine.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.medicine_management_system.common.commonReturn.CommonCodeEnum;
import com.xyht.medicine_management_system.common.commonReturn.CommonResult;
import com.xyht.medicine_management_system.common.commonReturn.ResponseResult;
import com.xyht.medicine_management_system.common.util.ApiModelUtil;
import com.xyht.medicine_management_system.common.util.TimeUtil;
import com.xyht.medicine_management_system.modules.classification.entity.MmsMedicineClassification;
import com.xyht.medicine_management_system.modules.classification.mapper.MmsMedicineClassificationMapper;
import com.xyht.medicine_management_system.modules.collect.entity.MmsMedicineCollect;
import com.xyht.medicine_management_system.modules.collect.mapper.MmsMedicineCollectMapper;
import com.xyht.medicine_management_system.modules.common.entity.MmsImportTask;
import com.xyht.medicine_management_system.modules.common.entity.MmsImportTaskDetail;
import com.xyht.medicine_management_system.modules.common.mapper.MmsImportTaskDetailMapper;
import com.xyht.medicine_management_system.modules.common.mapper.MmsImportTaskMapper;
import com.xyht.medicine_management_system.modules.manufacturer.entity.MmsManufacturer;
import com.xyht.medicine_management_system.modules.manufacturer.mapper.MmsManufacturerMapper;
import com.xyht.medicine_management_system.modules.medicine.entity.*;
import com.xyht.medicine_management_system.modules.medicine.entity.req.*;
import com.xyht.medicine_management_system.modules.medicine.entity.resp.MmsMedicineManufacturerResp;
import com.xyht.medicine_management_system.modules.medicine.entity.resp.MmsMedicineClassificationResp;
import com.xyht.medicine_management_system.modules.medicine.entity.resp.MmsMedicineDetailResp;
import com.xyht.medicine_management_system.modules.medicine.entity.resp.MmsMedicineUserResp;
import com.xyht.medicine_management_system.modules.medicine.mapper.*;
import com.xyht.medicine_management_system.modules.medicine.service.MmsMedicineService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.medicine_management_system.modules.medicine.util.MedicineUtil;
import com.xyht.medicine_management_system.modules.medicineSource.entity.resp.MmsMedicineSourceAndMedicineRelationResp;
import com.xyht.medicine_management_system.modules.medicineSource.util.MedicineSourceUtil;
import com.xyht.medicine_management_system.modules.order.entity.MmsOrder;
import com.xyht.medicine_management_system.modules.order.entity.resp.OrderMedicineInfoResp;
import com.xyht.medicine_management_system.modules.order.mapper.MmsOrderMapper;
import com.xyht.medicine_management_system.modules.stock.entity.MmsMedicineStock;
import com.xyht.medicine_management_system.modules.stock.mapper.MmsMedicineStockMapper;
import com.xyht.medicine_management_system.modules.user.entity.MmsUser;
import com.xyht.medicine_management_system.modules.user.mapper.MmsUserMapper;
import com.xyht.medicine_management_system.modules.visit.entity.MmsMedicineVisit;
import com.xyht.medicine_management_system.modules.visit.mapper.MmsMedicineVisitMapper;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.medicine_management_system.modules.classification.constant.QualificationConstant.QUALIFICATION_NONE;
import static com.xyht.medicine_management_system.modules.collect.constant.CollectTypeConstant.COLLECT_TYPE_MEDICINE;
import static com.xyht.medicine_management_system.modules.common.constant.SheetCommonConstant.PER_SHEET_NUM;
import static com.xyht.medicine_management_system.modules.common.constant.TaskDetailReason.*;
import static com.xyht.medicine_management_system.modules.common.constant.TaskNameExample.TASK_NAME_MEDICINE_IMPORT;
import static com.xyht.medicine_management_system.modules.common.constant.TaskStatus.TASK_STATUS_DONE;
import static com.xyht.medicine_management_system.modules.common.constant.TaskStatus.TASK_STATUS_ERR;
import static com.xyht.medicine_management_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_MEDICINE;
import static com.xyht.medicine_management_system.modules.medicine.constant.MedicineCollectFlagConstant.MEDICINE_COLLECT;
import static com.xyht.medicine_management_system.modules.medicine.constant.MedicineCollectFlagConstant.MEDICINE_NOT_COLLECT;
import static com.xyht.medicine_management_system.modules.medicine.constant.MedicineIsOnConstant.MEDICINE_IS_OFF;
import static com.xyht.medicine_management_system.modules.medicine.constant.MedicineIsOnConstant.MEDICINE_IS_ON;
import static com.xyht.medicine_management_system.modules.medicine.constant.MedicineIsSpecialConstant.MEDICINE_IS_NOT_SPECIAL;
import static com.xyht.medicine_management_system.modules.medicine.constant.MedicineIsSpecialConstant.MEDICINE_IS_SPECIAL;
import static com.xyht.medicine_management_system.modules.medicineSource.constant.IdTypeConstant.ID_TYPE_MEDICINE;
import static com.xyht.medicine_management_system.modules.user.constant.QualificationTypeConstant.QUALIFICATION_TYPE_NONE;

/**
 * <p>
 * 药品 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-11-29
 */
@Service
public class MmsMedicineServiceImpl extends ServiceImpl<MmsMedicineMapper, MmsMedicine> implements MmsMedicineService {

    @Resource
    private MmsMedicineMapper medicineMapper;
    @Resource
    private MmsMedicineSpecialMapper medicineSpecialMapper;
    @Resource
    private MmsUserMapper userMapper;
    @Resource
    private MmsMedicineClassificationMapper medicineClassificationMapper;
    @Resource
    private MmsManufacturerMapper manufacturerMapper;
    @Resource
    private MedicineUtil medicineUtil;
    @Resource
    private MmsMedicineStockMapper medicineStockMapper;
    @Resource
    private MmsMedicineHotMapper medicineHotMapper;
    @Resource
    private MmsMedicineRecommendMapper medicineRecommendMapper;
    @Resource
    private MedicineSourceUtil medicineSourceUtil;
    @Resource
    private MmsImportTaskMapper mmsImportTaskMapper;
    @Resource
    private MmsImportTaskDetailMapper mmsImportTaskDetailMapper;
    @Resource
    private PlatformTransactionManager transactionManager;
    @Resource
    private ApiModelUtil apiModelUtil;
    @Resource
    private MmsMedicineCollectMapper medicineCollectMapper;
    @Resource
    private MmsMedicineVisitMapper medicineVisitMapper;
    @Resource
    private MmsOrderMapper mmsOrderMapper;





    @Override
    @Transactional
    public ResponseResult addMedicine(String userId, MmsMedicineAddReq addReq) {
        if (isNullOrEmpty(addReq.getCommonNames(),addReq.getMedicineCode(),addReq.getSalesPrice(),addReq.getMarketPrice(),addReq.getClassificationId(), addReq.getManufacturer(),
                addReq.getMainPic(),addReq.getCarouselPic(),addReq.getDetailPic())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        //商品编码唯一
        List<MmsMedicine> medicines = medicineMapper.selectList(new LambdaQueryWrapper<MmsMedicine>()
                .eq(MmsMedicine::getMedicineCode, addReq.getMedicineCode()));
        if (!medicines.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.MEDICINE_CODE_REPEAT);
        }
        //添加药品
        MmsMedicine addMedicine = new MmsMedicine();
        BeanUtils.copyProperties(addReq,addMedicine);
        addMedicine.setCreateUserId(userId);
        medicineMapper.insert(addMedicine);

        //添加库存 默认0
        MmsMedicineStock medicineStock = new MmsMedicineStock();
        medicineStock.setMedicineId(addMedicine.getId());
        medicineStock.setStockQuantity(0);
        medicineStockMapper.insert(medicineStock);


        return CommonResult.success();
    }

    @Override
    public ResponseResult updateMedicine(MmsMedicineUpdateReq updateReq) {
        if (isNullOrEmpty(updateReq.getId(),updateReq.getMedicineCode(),updateReq.getSalesPrice(),updateReq.getCommonNames(),updateReq.getMarketPrice(),updateReq.getClassificationId(),
                updateReq.getManufacturer(),updateReq.getMainPic(),updateReq.getCarouselPic(),updateReq.getDetailPic())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        MmsMedicine medicine = medicineMapper.selectById(updateReq.getId());
        if (isNullOrEmpty(medicine)) {
            return CommonResult.failed(CommonCodeEnum.MEDICINE_NOT_EXIST);
        }
        //检验药品编码
        String oldMedicineCode = medicine.getMedicineCode();
        if (!oldMedicineCode.equals(updateReq.getMedicineCode())) {
            //商品编码唯一
            List<MmsMedicine> medicines = medicineMapper.selectList(new LambdaQueryWrapper<MmsMedicine>()
                    .eq(MmsMedicine::getMedicineCode, updateReq.getMedicineCode()));
            if (!medicines.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.MEDICINE_CODE_REPEAT);
            }
        }

        BeanUtils.copyProperties(updateReq,medicine);
        medicineMapper.updateById(medicine);
        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult deletedMedicine(MmsMedicineDeletedReq deletedReq) {
        if (isNullOrEmpty(deletedReq.getMedicineId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        MmsMedicine mmsMedicine = medicineMapper.selectById(deletedReq.getMedicineId());

        if (isNullOrEmpty(mmsMedicine)) {
            return CommonResult.failed(CommonCodeEnum.MEDICINE_NOT_EXIST);
        }

        //上架状态
        Integer isOn = mmsMedicine.getIsOn();
        if (isOn == MEDICINE_IS_ON) {
            return CommonResult.failed(CommonCodeEnum.MEDICINE_NOT_IS_OFF);
        }
        medicineMapper.deleteById(deletedReq.getMedicineId());

        //删除库存表
        medicineStockMapper.delete(new LambdaQueryWrapper<MmsMedicineStock>()
                .eq(MmsMedicineStock::getMedicineId, deletedReq.getMedicineId()));

        //删除热销药品
        medicineHotMapper.delete(new LambdaQueryWrapper<MmsMedicineHot>()
                .eq(MmsMedicineHot::getMedicineId, deletedReq.getMedicineId()));
        //删除推荐药品
        medicineRecommendMapper.delete(new LambdaQueryWrapper<MmsMedicineRecommend>()
                .eq(MmsMedicineRecommend::getMedicineId, deletedReq.getMedicineId()));
        //删除特惠药品
        medicineSpecialMapper.delete(new LambdaQueryWrapper<MmsMedicineSpecial>()
                .eq(MmsMedicineSpecial::getMedicineId, deletedReq.getMedicineId()));

        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult getMedicineDetail(String id, String userId) {
        if (isNullOrEmpty(id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        MmsMedicine medicine = medicineMapper.selectById(id);
        if (isNullOrEmpty(medicine)) {
            return CommonResult.failed(CommonCodeEnum.MEDICINE_NOT_EXIST);
        }
        MmsMedicineDetailResp medicineDetailResp = new MmsMedicineDetailResp();
        BeanUtils.copyProperties(medicine,medicineDetailResp);
        //查库存
        List<MmsMedicineStock> medicineStockList = medicineStockMapper.selectList(new LambdaQueryWrapper<MmsMedicineStock>()
                .eq(MmsMedicineStock::getMedicineId, id));
        if (medicineStockList.isEmpty()) {
            medicineDetailResp.setStockQuantity(0);
        }else {
            medicineDetailResp.setStockQuantity(medicineStockList.get(0).getStockQuantity());
        }
        //分类
        MmsMedicineClassification medicineClassification = medicineClassificationMapper.selectById(medicine.getClassificationId());
        if (!isNullOrEmpty(medicineClassification)) {
            MmsMedicineClassificationResp classificationResp = new MmsMedicineClassificationResp();
            BeanUtils.copyProperties(medicineClassification,classificationResp);
            medicineDetailResp.setClassificationInfo(classificationResp);
        }
        //厂家
        MmsManufacturer mmsManufacturer = manufacturerMapper.selectById(medicine.getManufacturer());
        if (!isNullOrEmpty(mmsManufacturer)) {
            MmsMedicineManufacturerResp manufacturerResp = new MmsMedicineManufacturerResp();
            BeanUtils.copyProperties(mmsManufacturer,manufacturerResp);
            medicineDetailResp.setManufacturerInfo(manufacturerResp);
        }

        //判断是否特惠商品
        List<MmsMedicineSpecial> specialList = medicineSpecialMapper.selectList(new LambdaQueryWrapper<MmsMedicineSpecial>()
                .eq(MmsMedicineSpecial::getMedicineId, medicine.getId()));
        if (specialList != null && specialList.size() > 0 ) {
            medicineDetailResp.setIsSpecial(MEDICINE_IS_SPECIAL);
            medicineDetailResp.setSpecialPrice(specialList.get(0).getSpecialPrice());
        } else {
            medicineDetailResp.setIsSpecial(MEDICINE_IS_NOT_SPECIAL);
        }

        //药资源
        List<MmsMedicineSourceAndMedicineRelationResp> medicineRelationList = medicineSourceUtil.getRelationList(id, ID_TYPE_MEDICINE);
        medicineDetailResp.setMedicineRelationInfo(medicineRelationList);

        //收藏标识
        List<MmsMedicineCollect> medicineCollects = medicineCollectMapper.selectList(new LambdaQueryWrapper<MmsMedicineCollect>()
                .eq(MmsMedicineCollect::getCollectId, medicine.getId())
                .eq(MmsMedicineCollect::getUserId, userId));
        if (!medicineCollects.isEmpty()) {
            medicineDetailResp.setCollectFlag(MEDICINE_COLLECT);
            medicineDetailResp.setCollectId(medicineCollects.get(0).getId());
        }else {
            medicineDetailResp.setCollectFlag(MEDICINE_NOT_COLLECT);
        }
        if (!isNullOrEmpty(userId)) {
            //添加药品足迹
            medicineUtil.addFootprint(medicine, userId);

            //添加访问记录
            MmsMedicineVisit addMedicineVisit = new MmsMedicineVisit();
            addMedicineVisit.setVisitId(id);
            addMedicineVisit.setVisitType(COLLECT_TYPE_MEDICINE);
            addMedicineVisit.setUserId(userId);
            medicineVisitMapper.insert(addMedicineVisit);
        }


        //本月的销售额
        //本月第一天
        Date startMonth = TimeUtil.GetStartDateOfMonth(new Date());
        //本月的最后一天
        Date endDateOfMonth = TimeUtil.GetEndDateOfMonth(startMonth);


        List<MmsOrder> orderList = mmsOrderMapper.selectList(new LambdaQueryWrapper<MmsOrder>()
                .like(MmsOrder::getMedicineInfo, id)
                .ge(MmsOrder::getPaymentTime, startMonth)
                .le(MmsOrder::getPaymentTime, endDateOfMonth));
        int salesVolume = 0;
        if (orderList.isEmpty()) {
            medicineDetailResp.setSalesVolume(salesVolume);
            return CommonResult.success(medicineDetailResp);
        }


        for (MmsOrder order : orderList) {
            String medicineInfo = order.getMedicineInfo();
            List<OrderMedicineInfoResp> respList = JSON.parseArray(medicineInfo, OrderMedicineInfoResp.class);
            if (respList.isEmpty()) {
                continue;
            }
            List<OrderMedicineInfoResp> medicineInfoRespList = respList.stream().filter(i -> i.getMedicine().getId().equals(id)).collect(Collectors.toList());
            if (medicineInfoRespList.isEmpty()) {
                continue;
            }
            for (OrderMedicineInfoResp orderMedicineInfoResp : medicineInfoRespList) {
                salesVolume += orderMedicineInfoResp.getMedicineNum();
            }
        }

        medicineDetailResp.setSalesVolume(salesVolume);

        return CommonResult.success(medicineDetailResp);
    }

    @Override
    public ResponseResult getMedicineList(String name, String type, Integer isOn, Integer pageSize, Integer pageNum, String userId) {
        Page<MmsMedicine> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<MmsMedicine> lambdaQueryWrapper = new LambdaQueryWrapper<MmsMedicine>().orderByDesc(MmsMedicine::getCreateTime);
        LambdaQueryWrapper<MmsMedicineClassification> classificationLambdaQueryWrapper = new LambdaQueryWrapper<>();

        //构造检验药品分类资质条件
        boolean flag = false;
        if (!isNullOrEmpty(userId)) {
            MmsUser mmsUser = userMapper.selectById(userId);
            if (mmsUser != null) {
                flag = true;

            }
        }
        //1.flag为true时有 用户登录及用户信息
        if (flag) {
            //查用户资质
            MmsUser mmsUser = userMapper.selectById(userId);
            Integer qualificationType = mmsUser.getQualificationType();
            //用户没有资质时,只能查看没有资质分类的药品
            if (qualificationType == QUALIFICATION_TYPE_NONE) {
                //不需要资质的分类
                List<MmsMedicineClassification> classificationList = medicineClassificationMapper.selectList(
                        classificationLambdaQueryWrapper.eq(MmsMedicineClassification::getIsQualification, qualificationType));
                if (!classificationList.isEmpty()) {
                    List<String> classificationIdList = classificationList.stream().map(MmsMedicineClassification::getId).collect(Collectors.toList());
                    lambdaQueryWrapper.in(MmsMedicine::getClassificationId,classificationIdList);
                }else {
                    lambdaQueryWrapper.in(MmsMedicine::getClassificationId,"");
                }
            }
        //2.flag为false时没有 用户登录及用户信息
        }else {
            //用户未登录只能查看不需要资质的分类药品
            List<MmsMedicineClassification> classificationList = medicineClassificationMapper.selectList(classificationLambdaQueryWrapper
                    .eq(MmsMedicineClassification::getIsQualification, QUALIFICATION_NONE));
            if (!classificationList.isEmpty()) {
                List<String> classificationIdList = classificationList.stream().map(MmsMedicineClassification::getId).collect(Collectors.toList());
                if (!classificationIdList.isEmpty()) {
                    lambdaQueryWrapper.in(MmsMedicine::getClassificationId,classificationIdList);
                } else {
                    lambdaQueryWrapper.in(MmsMedicine::getClassificationId,"");
                }

            }else {
                lambdaQueryWrapper.in(MmsMedicine::getClassificationId,"");
            }
        }
        //药品名称
        if (!isNullOrEmpty(name)) {
            lambdaQueryWrapper.and(
                    i -> i.like(MmsMedicine::getCommonNames, name)
                    .or()
                    .like(MmsMedicine::getMedicineCode, name));
        }
        //药品分类
        if (!isNullOrEmpty(type)) {
            lambdaQueryWrapper.eq(MmsMedicine::getClassificationId,type);
        }
        if (!isNullOrEmpty(isOn)) {
            lambdaQueryWrapper.eq(MmsMedicine::getIsOn,isOn);
        }
        medicineMapper.selectPage(page,lambdaQueryWrapper);

        List<MmsMedicineDetailResp> medicineDetailList = page.getRecords()
                .stream()
                .map(mmsMedicine -> {
                    MmsMedicineDetailResp medicineDetailResp = new MmsMedicineDetailResp();
                    BeanUtils.copyProperties(mmsMedicine, medicineDetailResp);

                    //查库存
                    List<MmsMedicineStock> medicineStockList = medicineStockMapper.selectList(new LambdaQueryWrapper<MmsMedicineStock>()
                            .eq(MmsMedicineStock::getMedicineId, mmsMedicine.getId()));
                    if (medicineStockList.isEmpty()) {
                        medicineDetailResp.setStockQuantity(0);
                    }else {
                        medicineDetailResp.setStockQuantity(medicineStockList.get(0).getStockQuantity());
                    }
                    //判断是否特惠商品
                    List<MmsMedicineSpecial> specialList = medicineSpecialMapper.selectList(new LambdaQueryWrapper<MmsMedicineSpecial>()
                            .eq(MmsMedicineSpecial::getMedicineId, mmsMedicine.getId()));
                    if (specialList != null && specialList.size() > 0 ) {
                        medicineDetailResp.setIsSpecial(MEDICINE_IS_SPECIAL);
                        medicineDetailResp.setSpecialPrice(specialList.get(0).getSpecialPrice());
                    } else {
                        medicineDetailResp.setIsSpecial(MEDICINE_IS_NOT_SPECIAL);
                    }


                    //分类
                    MmsMedicineClassification medicineClassification = medicineClassificationMapper.selectById(mmsMedicine.getClassificationId());
                    if (!isNullOrEmpty(medicineClassification)) {
                        MmsMedicineClassificationResp classificationResp = new MmsMedicineClassificationResp();
                        BeanUtils.copyProperties(medicineClassification,classificationResp);
                        medicineDetailResp.setClassificationInfo(classificationResp);
                    }
                    //厂家
                    MmsManufacturer mmsManufacturer = manufacturerMapper.selectById(mmsMedicine.getManufacturer());
                    if (!isNullOrEmpty(mmsManufacturer)) {
                        MmsMedicineManufacturerResp manufacturerResp = new MmsMedicineManufacturerResp();
                        BeanUtils.copyProperties(mmsManufacturer,manufacturerResp);
                        medicineDetailResp.setManufacturerInfo(manufacturerResp);
                    }

                    MmsUser mmsUser = userMapper.selectById(mmsMedicine.getCreateUserId());
                    if (!isNullOrEmpty(mmsUser)) {
                        MmsMedicineUserResp user = new MmsMedicineUserResp();
                        BeanUtils.copyProperties(mmsUser,user);
                        medicineDetailResp.setUserInfo(user);
                    }
                    return medicineDetailResp;
                })
                .collect(Collectors.toList());

        int total = (int)page.getTotal();
        return CommonResult.success(medicineDetailList,total);
    }

    @Override
    @Async
    public Future<ResponseResult> batchAddMedicine(Map<String, Object> map, String user_id) {
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(map));
        List<MmsMedicine> medicinesBatchReqs = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("list")), MmsMedicine.class);
        if (medicinesBatchReqs == null || medicinesBatchReqs.size() < 1) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
//        List<MmsMedicinePicReq> medicinePicList = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("picList")), MmsMedicinePicReq.class);
        //创建导入任务
        MmsImportTask smsImportTask = new MmsImportTask();
        smsImportTask.setTaskName(TASK_NAME_MEDICINE_IMPORT);
        smsImportTask.setUserId(user_id);
        smsImportTask.setTaskType(TASK_TYPE_MEDICINE);
        mmsImportTaskMapper.insert(smsImportTask);
        batchAddMedicineInfo(medicinesBatchReqs, smsImportTask.getId(),user_id);
        return new AsyncResult<>(CommonResult.success());
    }

    private void batchAddMedicineInfo(List<MmsMedicine> medicineBatchReqs, String id,String userId) {

        int OFFSET_ROW = 1;
        int task_status = TASK_STATUS_DONE;
        for (int i = 0; i < medicineBatchReqs.size(); i++) {
            //开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            try {
                MmsMedicine storage = medicineBatchReqs.get(i);
                if (isNullOrEmpty(storage.getCommonNames(),storage.getMedicineCode(),storage.getSalesPrice(),storage.getMarketPrice(),storage.getClassificationId())) {
                    transactionManager.rollback(status);
                    task_status = TASK_STATUS_ERR;
                    createTeacherImportTaskDetail(id, REASON_INVALID_PARAM, (i + OFFSET_ROW) + "");
                    continue;
                }
                MmsMedicine medicine = new MmsMedicine();
                BeanUtils.copyProperties(storage, medicine);
                medicine.setCreateUserId(userId);

//                //图片
//                String carouselPic = storage.getCarouselPic();//轮播图
//                String detailPic = storage.getDetailPic();//详情图
//                String mainPic = storage.getMainPic();//主图
//                if (!medicinePicList.isEmpty() && !isNullOrEmpty(carouselPic)) {
//                    String picName = null;
//                    List<MmsMedicinePicReq> picReqList = medicinePicList.stream()
//                            .filter(picReq -> picReq.getOldPicName().equals(carouselPic)).collect(Collectors.toList());
//                    if (picReqList.size() == 1) {
//                        picName = picReqList.get(0).getPicName();
//                    }
//
//                }
                //分类
                List<MmsMedicineClassification> mmsMedicineClassifications = medicineClassificationMapper.selectList(new LambdaQueryWrapper<MmsMedicineClassification>()
                            .eq(MmsMedicineClassification::getName, storage.getClassificationId()));
                if (mmsMedicineClassifications.isEmpty()) {
                    transactionManager.rollback(status);
                    task_status = TASK_STATUS_ERR;
                    createTeacherImportTaskDetail(id, REASON_CLASSIFICATION_NOT_EXIST, (i + OFFSET_ROW) + "");
                    continue;
                }
                medicine.setClassificationId(mmsMedicineClassifications.get(0).getId());

                //厂家
                if (!isNullOrEmpty(storage.getManufacturer())) {
                    List<MmsManufacturer> mmsManufacturers = manufacturerMapper.selectList(new LambdaQueryWrapper<MmsManufacturer>()
                            .eq(MmsManufacturer::getMfName, storage.getManufacturer()));
                    if (!mmsManufacturers.isEmpty()) {
                        medicine.setManufacturer(mmsManufacturers.get(0).getId());
                    }
                }
                //商品编码有则更新 没有则新增
                List<MmsMedicine> medicines = medicineMapper.selectList(new LambdaQueryWrapper<MmsMedicine>()
                        .eq(MmsMedicine::getMedicineCode, storage.getMedicineCode()));
                if (medicines.isEmpty()) {
                    medicineMapper.insert(medicine);
                }else {
                    medicineMapper.update(medicine,new LambdaQueryWrapper<MmsMedicine>()
                    .eq(MmsMedicine::getMedicineCode,storage.getMedicineCode()));
                }


                //创建仓库
                MmsMedicineStock medicineStock = new MmsMedicineStock();
                medicineStock.setMedicineId(medicine.getId());
                medicineStock.setStockQuantity(0);
                medicineStockMapper.insert(medicineStock);

                transactionManager.commit(status);
            } catch (Exception e) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createTeacherImportTaskDetail(id, REASON_IMPORT_ERR, (i + OFFSET_ROW) + "");
            }finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    transactionManager.commit(status);
                }
            }
        }
        MmsImportTask smsImportTask = new MmsImportTask();
        smsImportTask.setId(id);
        smsImportTask.setStatus(task_status);
        mmsImportTaskMapper.updateById(smsImportTask);
    }

    private void createTeacherImportTaskDetail(String id, String reason, String row) {
        MmsImportTaskDetail smsImportTaskDetail = new MmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(id);
        smsImportTaskDetail.setFailReason(reason);
        smsImportTaskDetail.setFailRow(row);
        mmsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }

    @Override
    @Async
    public Future<ResponseResult> exportMedicine(MmsMedicineExportReq req, HttpServletResponse response) {
        try {
            LambdaQueryWrapper<MmsMedicine> medicineLambdaQueryWrapper = new LambdaQueryWrapper<>();
            //药品名称
            if (!isNullOrEmpty(req.getCommonName())) {
                medicineLambdaQueryWrapper.like(MmsMedicine::getCommonNames,req.getCommonName());
            }
            //药品编码
            if (!isNullOrEmpty(req.getMedicineCode())) {
                medicineLambdaQueryWrapper.like(MmsMedicine::getMedicineCode,req.getMedicineCode());
            }
            //药品分类
            if (!isNullOrEmpty(req.getClassificationName())) {
                medicineLambdaQueryWrapper.eq(MmsMedicine::getClassificationId,req.getClassificationName());
            }
            //是否上架
            if (!isNullOrEmpty(req.getIsOn())) {
                medicineLambdaQueryWrapper.eq(MmsMedicine::getIsOn,req.getIsOn());
            }
            medicineLambdaQueryWrapper.orderByDesc(MmsMedicine::getCreateTime);
            List<MmsMedicine> list = medicineMapper.selectList(medicineLambdaQueryWrapper);
            //表头数据
            String[] header = req.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (list != null && list.size() > 0) {
                sheetNum = Math.ceil((double) list.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("药品信息导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头(下面模拟遍历学生，也是同样的操作过程)
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(MmsMedicine.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }


                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = list.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        MmsMedicine medicine = list.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(medicine), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if(!isNullOrEmpty(map.get(header[j]))) {
                                //创建人
                                if (header[j].equals("createUserId")) {
                                    MmsUser mmsUser = userMapper.selectById(medicine.getCreateUserId());
                                    if (mmsUser != null) {
                                        rowContent = mmsUser.getNickName();
                                    } else {
                                        rowContent = "";
                                    }
                                    //分类
                                } else if (header[j].equals("classificationId")) {
                                    MmsMedicineClassification mmsMedicineClassification = medicineClassificationMapper.selectById(medicine.getClassificationId());
                                    if (!isNullOrEmpty(mmsMedicineClassification)) {
                                        rowContent = mmsMedicineClassification.getName();
                                    } else {
                                        rowContent = "";
                                    }
                                    //厂家
                                } else if (header[j].equals("manufacturer")) {
                                    MmsManufacturer mmsManufacturer = manufacturerMapper.selectById(medicine.getManufacturer());
                                    if (!isNullOrEmpty(mmsManufacturer)) {
                                        rowContent = mmsManufacturer.getMfName();
                                    }
                                }else if(header[j].equals("manufactureDate")){
                                    Date manufactureDate = medicine.getManufactureDate();
                                    if (!isNullOrEmpty(manufactureDate)) {
                                        rowContent = TimeUtil.DateHanZiSimpleFormat(manufactureDate);
                                    }else {
                                        rowContent = "";
                                    }
                                } else {
                                    rowContent = String.valueOf(map.get(header[j]));
                                }
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                        }

                    }
                }
            }

            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("药品信息导出表.xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("药品信息导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();
            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }

    @Override
    public ResponseResult checkIsMedicine(String id) {
        if (isNullOrEmpty(id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        MmsMedicine medicine = medicineMapper.selectById(id);
        //商品不存在
        if (isNullOrEmpty(medicine)) {
            return CommonResult.success(false);
        }
        Integer isOn = medicine.getIsOn();
        //商品下架
        if (isOn == MEDICINE_IS_OFF) {
            return CommonResult.success(false);
        }
        return CommonResult.success(true);
    }


}
